<template>
  <a-drawer :closable="true" :title="title" :visible="visible" :width="width" @close="close">
    <a-spin :spinning="confirmLoading">
      <a-form :form="form">
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="实例标识">
          <a-input placeholder="请输入实例标识" v-decorator="['code', validatorRules.code]"></a-input>
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="实例名称">
          <a-input placeholder="请输入实例名称" v-decorator="['name', validatorRules.name]"></a-input>
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="设备模型">
          <j-search-select-tag :trigger-change="true" @change="val => (this.model.modelBy = val)" dict="iot_device_model,name,id" v-decorator="['modelBy', validatorRules.modelBy]" />
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="上级实例">
          <a-tree-select :allow-clear="true" :tree-data="parentInsSource" @change="val => (model.parentBy = val)" placeholder="请选择上级实例" v-decorator="['parentBy', validatorRules.parentBy]" />
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="所属机构">
          <!--                    <j-select-depart-->
          <!--                        :multi="false"-->
          <!--                        :trigger-change="true"-->
          <!--                        @change="val=>model.sysOrgCode=val"-->
          <!--                        customReturnField="orgCode"-->
          <!--                        v-decorator="['sysOrgCode', validatorRules.sysOrgCode]"-->
          <!--                    />-->
          <j-tree-select
            :trigger-change="true"
            v-decorator="['sysOrgCode', validatorRules.sysOrgCode]"
            placeholder="请选择组织机构"
            dict="sys_depart,depart_name,org_code"
            pidField="parent_id"
            @change="val => (model.sysOrgCode = val)"
          >
          </j-tree-select>
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="所属场景">
          <a-select :disabled="model.parentBy !== undefined && model.parentBy !== ''" @change="val => (model.sceneBy = val)" v-decorator="['sceneBy', validatorRules.sceneBy]">
            <a-select-option :key="scene.value" v-for="scene in sceneSource">
              {{ scene.text }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="场景方案">
          <a-select :disabled="model.parentBy !== undefined && model.parentBy !== ''" @change="val => (model.sceneSchemeBy = val)" v-decorator="['sceneSchemeBy', validatorRules.sceneSchemeBy]">
            <a-select-option :key="sceneScheme.value" v-for="sceneScheme in sceneSchemeSource">
              {{ sceneScheme.text }}
            </a-select-option>
          </a-select>
        </a-form-item>
        <a-form-item :labelCol="labelCol" :wrapperCol="wrapperCol" label="说明">
          <a-textarea placeholder="请输入说明" rows="4" v-decorator="['description', validatorRules.description]" />
        </a-form-item>
        <template v-if="model.extendParams">
          <template v-for="(extendParam, extendParamIndex) in model.extendParams">
            <a-card :title="'功能定义：' + extendParam.funcName" hoverable style="margin-bottom: 10px" :key="extendParamIndex">
              <div :key="inputParamIndex" v-for="(inputParam, inputParamIndex) in extendParam.inputParams">
                <a-form-item
                  :label="inputParam.name"
                  :labelCol="labelCol"
                  :wrapperCol="wrapperCol"
                  validate-status="warning"
                >
                  <template v-if="'string'.indexOf(inputParam.type) !== -1">
                    {{model.extendParams[extendParamIndex].inputParams[inputParamIndex].value}}
                    <a-input
                      :placeholder="'请输入' + inputParam.name"
                      @change="e => model.extendParams[extendParamIndex].inputParams[inputParamIndex].value = e.target.value"
                      v-decorator="[
                        // extendParam[0].inputParam[0]
                        `functions.${extendParam.funcCode}.${inputParam.code}`,
                        {
                          initialValue: inputParam.value || inputParam.metadata.defaultValue,
                          rules: [
                            { required: true, message: '请输入' + inputParam.name },
                            { max: inputParam.metadata.strLength - 0, message: '超出字符串最大长度：' + inputParam.metadata.strLength }
                          ]
                        }
                      ]"
                    ></a-input>
                  </template>
                  <template v-if="'ip'.indexOf(inputParam.type) !== -1">
                    <a-input
                      :placeholder="'请输入' + inputParam.name"
                      @change="e => model.extendParams[extendParamIndex].inputParams[inputParamIndex].value = e.target.value"
                      v-decorator="[
                        `functions.${extendParam.funcCode}.${inputParam.code}`,
                        {
                          initialValue: inputParam.value || inputParam.metadata.defaultValue,
                          rules: [
                            { required: true, message: '请输入' + inputParam.name },
                            {
                              pattern:
                                '^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$',
                              message: '请正确输入IP地址'
                            }
                          ]
                        }
                      ]"
                    ></a-input>
                  </template>
                  <template v-if="'ipPort'.indexOf(inputParam.type) !== -1">
                    <a-input
                      :placeholder="'请输入' + inputParam.name"
                      @change="e => model.extendParams[extendParamIndex]['inputParams'][inputParamIndex]['value'] = e.target.value"
                      v-decorator="[
                        `functions[${extendParamIndex}].inputParams[${inputParamIndex}]['value']`,
                        {
                          initialValue: inputParam.value || inputParam.metadata.defaultValue,
                          rules: [
                            { required: true, message: '请输入' + inputParam.name },
                            {
                              pattern:
                                '^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\:\\d{2,6}$',
                              message: '请正确输入TCP地址[IP:PORT]'
                            }
                          ]
                        }
                      ]"
                    ></a-input>
                  </template>
                  <template v-if="'address'.indexOf(inputParam.type) !== -1">
                    <a-input
                      :placeholder="'请输入' + inputParam.name"
                      v-decorator="[
                        `functions.${extendParam.funcCode}.${inputParam.code}`,
                        {
                          initialValue: inputParam.value || inputParam.metadata.defaultValue,
                          rules: [
                            { required: true, message: '请输入' + inputParam.name },
                            {
                              pattern:
                                '^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\:\\d{2,6}$',
                              message: '请正确输入TCP地址[IP:PORT]'
                            }
                          ]
                        }
                      ]"
                    ></a-input>
                  </template>
                  <template v-if="'int'.indexOf(inputParam.type) !== -1">
                    <a-input-number
                      :max="inputParam.metadata.maxValue"
                      :min="inputParam.metadata.minValue"
                      :placeholder="'请输入' + inputParam.name"
                      @change="e => model.extendParams[extendParamIndex].inputParams[inputParamIndex].value = e.target.value"
                      v-decorator="[
                        `functions.${extendParam.funcCode}.${inputParam.code}`,
                        {
                          initialValue: inputParam.value || inputParam.metadata.defaultValue,
                          rules: [{ required: true, message: '请输入' + inputParam.name }]
                        }
                      ]"
                    ></a-input-number>
                    &nbsp;<a-tag color="blue">{{ inputParam.metadata.unit }}</a-tag>
                  </template>
                  <template v-if="'float,double'.indexOf(inputParam.type) !== -1">
                    <a-input-number
                      :max="inputParam.metadata.maxValue"
                      :min="inputParam.metadata.minValue"
                      :placeholder="'请输入' + inputParam.name"
                      :precision="inputParam.metadata.accuracy"
                      @change="e => model.extendParams[extendParamIndex].inputParams[inputParamIndex].value = e.target.value"
                      v-decorator="[
                        `functions.${extendParam.funcCode}.${inputParam.code}`,
                        {
                          initialValue: inputParam.value || inputParam.metadata.defaultValue,
                          rules: [{ required: true, message: '请输入' + inputParam.name }]
                        }
                      ]"
                    ></a-input-number>
                    &nbsp;<a-tag color="blue">{{ inputParam.metadata.unit }}</a-tag>
                  </template>
                  <template v-if="'bool'.indexOf(inputParam.type) !== -1">
                    <a-switch
                      :checked="model.extendParams[extendParam.code][inputParam.code]"
                      :checkedChildren="inputParam.metadata.trueText"
                      :unCheckedChildren="inputParam.metadata.falseText"
                      @change="e => model.extendParams[extendParamIndex].inputParams[inputParamIndex].value = e.target.value"
                      v-decorator="[
                        `functions.${extendParam.funcCode}.${inputParam.code}`,
                        {
                          initialValue: inputParam.value || inputParam.metadata.defaultValue
                        }
                      ]"
                    />
                  </template>
                  <template v-if="'array'.indexOf(inputParam.type) !== -1">
                    {{`functions[${extendParamIndex}].inputParams[${inputParamIndex}]['value']`}}
                    <a-textarea
                      :placeholder="'请输入' + inputParam.name"
                      :rows="3"
                      v-model="model.extendParams[extendParamIndex].inputParams[inputParamIndex].value"
                    ></a-textarea>
                  </template>
                </a-form-item>
              </div>
            </a-card>
          </template>
        </template>
      </a-form>
    </a-spin>
    <div
      :style="{
        position: 'absolute',
        right: 0,
        bottom: 0,
        width: '100%',
        borderTop: '1px solid #e9e9e9',
        padding: '10px 16px',
        background: '#fff',
        textAlign: 'right',
        zIndex: 1
      }"
    >
      <a-button :style="{ marginRight: '10px' }" @click="handleOk" type="primary">确定</a-button>
      <a-button @click="close" type="">取消</a-button>
    </div>
  </a-drawer>
</template>

<script>
import pick from 'lodash.pick'
import {validateDuplicateValue} from '@/utils/util'
import JSearchSelectTag from '@/components/dict/JSearchSelectTag'
import JSelectDepart from '@/components/jeecgbiz/JSelectDepart'
import {getAction, httpAction} from '@api/manage'
import JTreeSelect from '../../../../../components/jeecg/JTreeSelect'

export default {
  name: 'DeviceInstanceModal',
  components: {
    JTreeSelect,
    JSearchSelectTag,
    JSelectDepart
  },
  data() {
    return {
      form: this.$form.createForm(this),
      title: '操作',
      width: 500,
      visible: false,
      showParentBy: false,
      extendParams: {},
      functions: [],
      model: {},
      parentInsSource: [],
      orgSource: [],
      sceneSchemeSource: [],
      sceneSource: [],

      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 }
      },
      confirmLoading: false,
      validatorRules: {
        parentBy: {
          rules: []
        },
        code: {
          rules: [{ required: true, message: '请输入实例标识!' }, { validator: (rule, value, callback) => validateDuplicateValue('iot_device_instance', 'code', value, this.model.id, callback) }]
        },
        name: {
          rules: [{ required: true, message: '请输入实例名称!' }]
        },
        modelBy: {
          rules: [{ required: true, message: '请输入设备模型!' }]
        },
        sysOrgCode: {
          rules: [{ required: true, message: '请输入所属机构!' }]
        },
        sceneBy: {
          rules: [{ required: true, message: '请选择所属场景!' }]
        },
        sceneSchemeBy: {
          rules: [{ required: true, message: '请选择场景方案!' }]
          // initialValue: this.model.sceneSchemeBy
        },
        description: {
          rules: []
        }
      },
      url: {
        add: '/device/instance/add',
        edit: '/device/instance/edit',
        getFunctionParams: '/device/instance/getFunctionParams',
        get: '/device/instance/queryById',
        listParent: '/device/instance/listParentInstanceByCurrentOrg',
        listScene: '/scene/manage/listSceneByCurrentOrg',
        listSchemeByScene: '/scene/sceneScheme/listBySceneId'
      }
    }
  },
  computed: {
    deviceModelBy() {
      return this.model.modelBy
    },
    parentBy() {
      return this.model.parentBy
    },
    sceneBy() {
      return this.model.sceneBy
    }
  },
  watch: {
    deviceModelBy(val, oval) {
      console.log('watch-deviceModelBy', oval, '=>', val)
      this.getExtendParams(val)
    },
    parentBy(val, oval) {
      console.log('1、上级设备变动===>>', oval, '=>', val)
      if (val !== '') this.resetScene()
      this.getScene()
      this.getInstanceByParentId(val)
    },
    sceneBy(val, oval) {
      console.log('watch-sceneBy', oval, '=>', val)
      if (oval !== undefined) this.resetSceneScheme()

      this.getSchemeByScene(val)
    }
  },
  methods: {
    validatorPattern(type, metadata) {
      let validatorPattern = { pattern: '', message: '' }
      if (type === 'array') {
        switch (metadata.arrayType) {
          case 'byte':
            validatorPattern.pattern = `^([0-9a-fA-F]{2}${metadata.arraySplit}){${metadata.arraySize - 1}}[0-9a-fA-F]{2}$`
            validatorPattern.message = `请输入${metadata.arraySize}位byte类型以${metadata.arraySplit === ' ' ? '空格' : metadata.arraySplit}为分隔符的数组`
            break
          case 'int':
            validatorPattern.pattern = `^([0-9]${metadata.arraySplit}){${metadata.arraySize - 1}}[0-9]$`
            break
          default:
            validatorPattern.pattern = `^(.${metadata.arraySplit}){${metadata.arraySize - 1}}.$`
        }
      }

      return validatorPattern
    },
    getExtendParams(modelId) {
      const self = this
      if (modelId) {
        console.log('>>> 获取扩展参数 <<<')
        getAction(this.url.getFunctionParams, { instanceId: this.model.id, modelId: modelId }).then(res => {
          if (res.success) {
            self.model['extendParams'] = res.result
            self.model['extendParams'].map(extendParam => {
              // 设置初始值
              extendParam['inputParams']
                .filter(inputParam => !inputParam.value)
                .map(inputParam => inputParam.value = inputParam.metadata.defaultValue)
              // 追加校验规则
              extendParam['inputParams'].map(inputParam => {
                self.validatorRules[inputParam.code] = {rules: []}
                self.validatorRules[inputParam.code].rules.push({ required: true, message: '请填写'+ inputParam.inputModeText +'!' })
                self.validatorRules[inputParam.code].rules.push(self.validatorPattern(inputParam.type, inputParam.metadata))
              })
            })
            console.log(self.validatorRules)
            console.log(self.model['extendParams'])
          }
        })
      }
    },
    getInstanceByParentId(parentId) {
      if (parentId === undefined) return
      const self = this
      getAction(this.url.get, { id: parentId }).then(res => {
        if (res.success) {
          self.model.sysOrgCode = res.result.sysOrgCode
          self.model.sceneBy = res.result.sceneBy
          self.model.sceneSchemeBy = res.result.sceneSchemeBy
          self.$nextTick(() => {
            console.log('4、根据上级设备，设置sysOrgCode、sceneBy、sceneSchemeBy', self.model.sysOrgCode, self.model.sceneBy, self.model.sceneSchemeBy)
            this.form.setFieldsValue(pick(this.model, 'sysOrgCode', 'sceneBy', 'sceneSchemeBy'))
          })
        }
      })
    },
    /* 权限控制 */
    getParentInstance() {
      const self = this
      getAction(this.url.listParent, {}).then(res => {
        if (res.success) {
          console.log('上级设备: ', res.result)
          self.parentInsSource = res.result
        }
      })
    },
    getScene() {
      const self = this
      this.sceneSource = []
      getAction(this.url.listScene, {}).then(res => {
        if (res.success) {
          console.log('2、获取所属场景===>> ', res.result)
          res.result.filter(scene => {
            self.sceneSource.push({
              value: scene.id,
              text: scene.name
            })
          })
        }
      })
    },
    getSchemeByScene(sceneId) {
      const self = this
      this.sceneSchemeSource = []
      if (sceneId === undefined || sceneId === '') {
        return
      }
      getAction(this.url.listSchemeByScene, { sceneId: sceneId }).then(res => {
        if (res.success) {
          console.log('3、获取场景方案===>> ', res.result)
          res.result.filter(scheme => {
            self.sceneSchemeSource.push({
              value: scheme.id,
              text: scheme.name
            })
          })
        }
      })
    },
    resetParentInstance() {
      console.log('重置上级实例。。。')
      this.model.sceneBy = undefined
      this.$nextTick(() => {
        this.form.setFieldsValue(pick(this.model, 'sceneBy'))
      })
    },
    resetScene() {
      console.log('重置场景。。。')
      this.model.sceneBy = undefined
      this.$nextTick(() => {
        this.form.setFieldsValue(pick(this.model, 'sceneBy'))
      })
    },
    resetSceneScheme() {
      console.log('重置场景方案。。。')
      this.model.sceneSchemeBy = undefined
      this.$nextTick(() => {
        this.form.setFieldsValue(pick(this.model, 'sceneSchemeBy'))
      })
    },
    add() {
      let record = {
        sysOrgCode: '',
        modelBy: '',
        parentBy: '',
        sceneBy: '',
        sceneSchemeBy: '',
        isFirstLoad: true
      }
      this.edit(record)
    },
    edit(record) {
      const self = this
      this.getParentInstance()
      // this.getScene()
      this.form.resetFields()
      this.model = Object.assign({}, record)
      this.visible = true
      this.extendParams = JSON.parse(record.extendParams || '{}')
      this.model['isFirstLoad'] = true
      this.$nextTick(() => {
        this.form.setFieldsValue(pick(this.model, 'code', 'parentBy', 'name', 'modelBy', 'sysOrgCode', 'sceneBy', 'sceneSchemeBy', 'description'))
      })
    },
    close() {
      this.model = {}
      this.extendParams = []
      this.sceneSource = []
      this.form.resetFields()
      this.visible = false
    },
    handleOk() {
      const self = this
      // 触发表单验证
      this.form.validateFields((err, values) => {
        if (!err) {
          self.confirmLoading = true
          let httpurl = ''
          let method = ''
          if (!this.model.id) {
            httpurl += this.url.add
            method = 'post'
          } else {
            httpurl += this.url.edit
            method = 'put'
          }
          console.log(this.model)
          let formData = JSON.parse(JSON.stringify(Object.assign(this.model, values)))
          // 删除metadata
          formData.extendParams.forEach(func => {
            func.inputParams.forEach(input => {
              delete input.metadata
            })
          })
          console.log(formData)
          httpAction(httpurl, formData, method)
            .then(res => {
              if (res.success) {
                self.$message.success(res.message)
                self.$emit('ok')
              } else {
                self.$message.warning(res.message)
              }
            })
            .finally(() => {
              self.confirmLoading = false
              self.close()
            })
        }
      })
    }
  }
}
</script>
